package com.lhq.tag_tales.once;

import com.lhq.tag_tales.model.domain.User;
import com.lhq.tag_tales.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.lhq.tag_tales.constant.UserConstant.SALT;

@Component
@Slf4j
public class InsertUsers {
    @Resource
    private UserService userService;

    /**
     * 批量插入用户数据
     */
    //@Scheduled(initialDelay = 0, fixedRate = Long.MX_VALUE)
    public void doInsertUsers() {
        log.info("定时任务开始执行");
        StopWatch watch = new StopWatch();
        watch.start();
        final int INSERT_NUM = 100000;
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < INSERT_NUM; i++){
            User user = new User();
            user.setUserName("coder_"+i);
            user.setUserAccount("coder_"+i);
            user.setAvatarUrl("");
            user.setGender(i%2);
            user.setUserPassword("coder_fun_"+i);
            user.setPhone("36636737");
            user.setEmail("coder"+i+"@qq.com");
            user.setIsValid(1);
            user.setPlanetCode("3333");
            userList.add(user);
        }
        //分批插入，减少了建立连接和关闭连接的时间。
        userService.saveBatch(userList,10000);
        watch.stop();
        log.info("插入完成,耗时：{} ms", watch.getTotalTimeMillis());
    }

    /**
     * 多线程批量插入用户数据
     */
    //@Scheduled(initialDelay = 0, fixedRate = Long.MAX_VALUE)
    public void doConcurrencyInsertUsers() {
        log.info("定时任务开始执行");
        StopWatch watch = new StopWatch();
        watch.start();
        //选用线程安全的集合
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        //创建10个线程池
        ExecutorService pool = Executors.newFixedThreadPool(10);
        int j = 0;
        final int batchSize = 10;
        for (int i = 0; i < 10; i++) {
            List<User> userList = Collections.synchronizedList(new ArrayList<>());
            do {
                j++;
                User user = new User();
                user.setUserName("coder_" + j);
                user.setUserAccount("coder_" + j);
                user.setAvatarUrl("");
                user.setGender(j % 2);
                String password = DigestUtils.md5DigestAsHex(("coder_fun_" + j + SALT).getBytes());
                user.setUserPassword(password);
                user.setPhone("36636737");
                user.setEmail("coder" + j + "@qq.com");
                user.setIsValid(1);
                user.setPlanetCode("3333");
                userList.add(user);
            } while (j % batchSize != 0);
            //创建异步插入和分批插入任务。异步任务需要注意，任务的执行顺序无所谓
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> userService.saveBatch(userList, batchSize),pool);
            //将任务添加到任务集合中
            futureList.add(future);
        }
        //等待所有任务完成
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
        watch.stop();
        log.info("插入完成,耗时：{} ms", watch.getTotalTimeMillis());
    }
}
